﻿
using Microsoft.Extensions.Options;

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;

using Xc.DataAccess.OneNetCore.Services;
using Xc.Logics.AepCoap.Models;
using Xc.Logics.OneNet;

namespace Xc.Logics.AepCoap.Services
{
    public class OneNetUploadService : IOneNetUploadService
    {
        private readonly IOneNetService aepCoapService;

        public OneNetUploadService(IOneNetService aepCoapService,IOptions<AppSetting> options)
        {
            this.aepCoapService = aepCoapService;
            aepCoapService.Options = options.Value.OneNetSetting;


        }
        public class ExecuteResult
        {
            public ExecuteResult(string deviceNumber, string iMEI, string iMSI, string message = null)
            {
                DeviceNumber = deviceNumber;
                IMEI = iMEI;
                IMSI = iMSI;
                Message = message;
            }

            public string DeviceNumber { get; set; }
            public string IMEI { get; set; }

            public string IMSI { get; set; }
            public string Message { get; set; }
            public DateTime DateTime { get; set; }
        }
        /// <summary>
        /// 更新设备中
        /// </summary>
        /// <param name="isUpdateOld">是否更新旧的设备</param>
        /// <param name="oldDevice">旧的设备列表</param>
        /// <param name="newDevcie">新的设备列表</param>
        /// <param name="action">上传完毕后回调</param>
        /// <returns></returns>
        public async Task UploadAsync(bool isUpdateOld, List<AddDeviceModel> newDevcie, Action<ExecuteResult> action, ObservableCollection<NbDeviceInfo> oldDevice = null)
        {

            var actions = newDevcie.Select(dev => new Func<Task>(async () =>
            {
                try
                {

                    NbDeviceInfo dd = null;
                    if (oldDevice != null)
                    {
                        dd = oldDevice.Where(p => p.AuthInfo.IMEI == dev.IMEI).FirstOrDefault();//匹配已有设备
                    }
                    if (dd == null)//新设备直接增加
                    {
                        var req = new CreateDeviceRequest { Title = dev.DeviceNumber, AuthInfo = new AuthInfo { IMEI = dev.IMEI, IMSI = dev.IMSI } };
                        var resp = await aepCoapService.CreateDevice(req);
                        dev.AddDeviceStatus = resp.Message;

                        if (resp.IsSuccess)
                        {
                            action?.Invoke(new ExecuteResult(dev.DeviceNumber, dev.IMEI, dev.IMSI));
                        }
                    }
                    else//设备已存在
                    {
                        string msgStr = "设备已存在";
                        dev.AddDeviceStatus = msgStr;
                        if (isUpdateOld && oldDevice != null)//更新设备
                        {
                            if (!dd.Title.Contains(dev.DeviceNumber))//设备名称与平台不一致
                            {
                                //设备名称与平台已有设备不一致。。。比较时间哪个最新，以哪个为准
                                if (dd.CreateTime >= dev.CreateTime)
                                {
                                    //平台设备创建的时间 比 需要新增设备的生产时间要晚
                                    dev.AddDeviceStatus = msgStr + "，平台数据最新";
                                }
                                else
                                {
                                    UpdateDevcieRequest updateDevcieRequest = new UpdateDevcieRequest();
                                    updateDevcieRequest.IMEI = dev.IMEI;
                                    updateDevcieRequest.IMSI = dev.IMSI;
                                    updateDevcieRequest.Title = dev.DeviceNumber;
                                    var resp1 = await aepCoapService.UpdateDevice(updateDevcieRequest);
                                    if (resp1.IsSuccess)
                                    {
                                        action?.Invoke(new ExecuteResult(dev.DeviceNumber, dev.IMEI, dev.IMSI, resp1.Message));
                                        dev.AddDeviceStatus = msgStr + "设备名称修改成功";
                                    }
                                    else
                                    {
                                        dev.AddDeviceStatus = msgStr + resp1.Message;

                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception err)
                {
                    dev.AddDeviceStatus = err.Message;

                }
            }));
            System.Collections.Concurrent.ConcurrentQueue<Func<Task>> actions1 = new System.Collections.Concurrent.ConcurrentQueue<Func<Task>>();
            foreach (var item in actions)
            {
                actions1.Enqueue(item);
            }
            List<Task> tasks = new List<Task>();
            for (int i = 0; i < 3; i++)
            {
                tasks.Add(Task.Run(async () =>
               {
                   while (actions1.TryDequeue(out var act))
                   {
                       await act.Invoke();
                       await Task.Delay(10);
                   }
               }));
            }
            await Task.WhenAll(tasks);

        }
    }
}
